实时视频风格迁移 -- 油画

Copyright © Quectel Wireless Solutions Co., Ltd. 2026. All rights reserved.


本项目是一个基于 Quectel Pi M2 智能主控板(RK3576)实现的 NPU 油画风格迁移示例,提供 两种 使用方式:

  • 实时视频风格迁移:MIPI 摄像头(IMX219)采集画面,送入 RK3576 NPU 运行 FastNeuralStyle 油画风格迁移模型(udnie INT8),实时转换后输出到屏幕显示,完整展示"摄像头取帧 → NPU 推理 → 屏幕显示"的链路。

  • 单张图片风格迁移:读取本地图片,经同一模型转换后按原图尺寸回缩放并保存,适合预览效果或批量出图。

两种模式共用同一套 RKNN 推理封装(librknn_style.so + rknn_style.py)。

开发资源汇总

开发配件清单

提示:开发配件只是作为参考,不同的开发环境可能会有所差异。

配件名称

数量

规格参数

Quectel Pi M2 智能主控板

1 块

RK3576,8 核,板载 NPU

IMX219 MIPI 摄像头模块

1 个

camera0 → /dev/video33,camera1 → /dev/video51

显示屏(可选)

1 块

HDMI 或 MIPI DSI,需运行 Wayland 桌面

Type-C 电源适配器

1 个

5V/3A,或使用板载供电口

FPC 排线、亚克力支架

若干

摄像头固定与走线

配件实物参考

(此处插入主控板 + 摄像头 + 显示屏的实物照片)

快速上手

开发准备

Quectel Pi M2 智能主控板出厂默认搭载 Debian 13(trixie) 系统镜像,本示例所需的 Python、GStreamer、OpenCV 以及 RKNN 运行时均已预装,无需再次烧录镜像或编译推理库,仅需按如下步骤操作即可。

本示例的关键技术指标如下:

项目

参数

采集分辨率

640×480 @ 30 fps(NV12)

推理输入尺寸

160×160,3 通道

推理精度

INT8(RK3576)

风格模型

udnie(FastNeuralStyle)

实时帧率

约 2.7 FPS(RK3576 实测 2.64~2.76 FPS)

单图转换耗时

594×559 图片约 350 ms(含读写约 0.4 s)

显示方式

Wayland(waylandsink),窗口或全屏

推理运行时

librknnrt API 2.3.2 / NPU 驱动 0.9.8

硬件连接

完成以下所有硬件连接操作:

  1. 摄像头连接:将 IMX219(或兼容的 MIPI 摄像头)通过 FPC 排线接入主控板的 MIPI CSI 接口,camera0 对应 /dev/video33,camera1 对应 /dev/video51。

  2. 显示连接:通过 HDMI 或 MIPI DSI 接入显示屏,并确保桌面用户 q 已登录 Wayland 会话(/run/user/1001/wayland-0),因为显示使用 waylandsink。

  3. 供电连接:接入 Type-C 电源(5V/3A),上电后系统自动进入桌面。

提示:连接完成后可用 v4l2-ctl --list-devices 确认摄像头是否在位,若在 rkisp_mainpath (platform:rkisp-vir0) 下看到 /dev/video33,即代表 camera0 已正常识别。

项目实现

获取代码

工程已预置在板端的 /m2_demo_youhua 目录,可通过 git 查看或更新:

cd /m2_demo_youhua
git status
git pull

若需重新获取,从 GitHub 仓库克隆:

git clone https://github.com/Quectel-Pi/demo-rknn-style-transfer.git

目录结构如下:

/m2_demo_youhua/
├── run_on_board.sh             启动摄像头 demo
├── stop_on_board.sh            停止摄像头 demo
├── convert_image.sh            单图转换入口
├── build.sh                    重新编译 librknn_style.so(通常不需要执行)
├── src/rknn_style.c            build.sh 的源码
├── librknn_style.so            已编译好的推理包装库
├── rknn_style.py               RKNN ctypes 封装,两个主程序共用
├── oil_painting_cam.py         摄像头 demo 主程序
├── image_style.py              单图转换主程序
├── cat.png / cat_painting.png  单图转换示例(原图 / 效果图)
└── models/rknn/
    └── udnie-9_int8_rk3576.rknn

安装依赖

本镜像已预装全部依赖,一般情况下无需安装。可用如下命令校验:

python3 -c "import cv2, numpy; print(cv2.__version__, numpy.__version__)"
python3 -c "import gi; gi.require_version('Gst', '1.0'); from gi.repository import Gst; print('gst ok')"
ls /usr/lib/librknnrt.so

依赖清单供参考:

依赖项

Debian 包名

作用

Python 3

python3

主程序运行环境

OpenCV

python3-opencv

图像缩放与色彩转换

NumPy

python3-numpy

张量数据组织

GStreamer 绑定

python3-gi

摄像头采集与屏幕显示管线

GStreamer 插件

gstreamer1.0-plugins-base、-good、-bad

v4l2src、videoconvert、waylandsink

RKNN 运行时

librknnrt.so(/usr/lib)

NPU 推理

运行程序

cd /m2_demo_youhua
./run_on_board.sh                  # 后台运行,640x480 窗口
./run_on_board.sh --fullscreen     # 全屏
./run_on_board.sh --fg             # 前台运行(Ctrl+C 退出)
./stop_on_board.sh                 # 停止
tail -f /tmp/demo_run.log          # 查看后台日志

首次成功启动时,日志中可看到模型与管线信息:

[rknn] 模型 /m2_demo_youhua/models/rknn/udnie-9_int8_rk3576.rknn
[rknn] api=2.3.2 driver=0.9.8
[rknn] 输入 160x160 C3
[info] 5 帧, 2.64 FPS

单张图片风格迁移

除实时视频外,工程还提供单图转换入口 convert_image.sh,推理过程与摄像头 demo 完全一致(160×160 INT8),转换结果默认按原图尺寸回缩放后保存。

cd /m2_demo_youhua
./convert_image.sh cat.png                        # 输出 cat_udnie.png(同目录)
./convert_image.sh cat.png -o out/cat_paint.jpg   # 指定文件名,自动建目录
./convert_image.sh cat.png -o out/                # 指定目录,自动命名
./convert_image.sh cat.png -d out/paintings       # 同上,显式目录参数
./convert_image.sh a.png b.png -d out/            # 批量转换
./convert_image.sh cat.png -o 'out/{stem}_{model}.png'

输出命名规则:

写法

结果

不给

<输入目录>/<输入名>_<风格>.<原扩展名>

-o 路径/文件名.jpg

使用该文件名;无扩展名时沿用源扩展名

-o 目录/ 或以 / 结尾

目录内自动命名,目录不存在会自动创建

-o 已存在的目录

目录内自动命名

-d 目录

目录内自动命名

{stem} / {model}

在文件名中替换为输入名 / 风格名

常用参数:

参数

说明

-m/--model

风格,本分支仅 udnie

--precision

int8(本分支仅提供 INT8 模型)

--keep-size

保留 160×160 模型输出尺寸,不做放大

--interp

回缩放插值:nearest/linear/cubic/lanczos(默认 lanczos)

-q/--quiet

只输出错误信息

正常转换时的日志如下:

[img] input: cat.png
model:  /m2_demo_youhua/models/rknn/udnie-9_int8_rk3576.rknn
size:   model input 160x160, 3 channel(s)
[594x559] -> [594x559]  350 ms  cat_udnie.png

操控方式

程序启动后无需额外操作,画面会持续以油画风格实时刷新;以 root 启动时脚本会自动切换到桌面用户 q 再运行,以访问 Wayland 显示。

操作

功能

./run_on_board.sh

后台运行,窗口模式

./run_on_board.sh --fullscreen

全屏显示

./run_on_board.sh --windowed

源尺寸窗口显示(默认)

./run_on_board.sh --fg

前台运行,Ctrl+C 退出

./run_on_board.sh --camera /dev/video51

切换到 camera1

./run_on_board.sh --frames 100

跑 100 帧后自动退出(0 = 一直跑)

./stop_on_board.sh

停止后台实例

tail -f /tmp/demo_run.log

实时查看帧率与日志

应用演示

下图为本工程 cat.png 的原图与经 udnie 模型转换后的效果对比:

../../../_images/image_Gpccbn2H4oYEJ5xe0jncwSfvnJb.webp ../../../_images/image_XckvbgbjboUIG0xzVY5cqOw5nub.webp

摄像头实时模式的效果可通过 ./run_on_board.sh 直接观察;如需录制演示视频,建议使用 --fullscreen 模式并配合屏幕录制。

常见问题及解决方案

程序启动 15 秒后自动退出,提示未收到帧

现象:

[错误] 15 秒未收到任何帧 —— 检查相机 /dev/video33 是否可用

解决方案:

  • 使用 v4l2-ctl --list-devices 确认摄像头已识别,camera0 应为 /dev/video33。

  • 检查 FPC 排线是否插紧、方向是否正确。

  • 若使用 camera1,需显式指定:./run_on_board.sh --camera /dev/video51。

日志出现 libv4l2 pixformat 报错

现象:

libv4l2: error getting pixformat: Invalid argument

解决方案:

  • 这是 v4l2src 在 ISP 直出通路上的无害告警,脚本已设置 GST_V4L2_FORCE_LIBV4L2=0 规避;只要后续能正常出帧(日志出现 [info] N 帧)即可忽略。

启动报错 Wayland socket not found

现象:

[error] Wayland socket not found: /run/user/1001/wayland-0; make sure q is logged in

解决方案:

  • 确认桌面用户已登录图形界面,waylandsink 必须运行在 Wayland 会话中。

  • 若桌面用户不是 q,通过环境变量指定:DEMO_USER=your_user ./run_on_board.sh。

提示缺少 librknn_style.so 或找不到模型

现象:

RuntimeError: 缺少 /m2_demo_youhua/librknn_style.so, 请先在本目录执行 ./build.sh
找不到风格 'udnie' 的 int8 模型, 预期在 /m2_demo_youhua/models/rknn

解决方案:

  • 确认 librknn_style.so 与 models/rknn/udnie-9_int8_rk3576.rknn 均存在于工程目录,本部署分支只保留运行所需文件。

  • 推理库丢失时才需要重新编译,编译前需准备 Rockchip 专有的 rknn_api.h:

apt-get install -y build-essential
mkdir -p /usr/include/rknn
# 从 SDK 的 external/rknpu2/runtime/Linux/librknn_api/include/ 拷贝 rknn_api.h 到该目录
cd /m2_demo_youhua && ./build.sh
  • build.sh 会按 ./include → /usr/include/rknn → SDK 目录的顺序查找头文件;在开发机交叉编译时可通过 REPO 指定 SDK 根目录。

帧率偏低(约 2.7 FPS)

现象:

[info] 10 帧, 2.76 FPS

解决方案:

  • 该帧率是当前 FastNeuralStyle 模型在 RK3576 NPU 上的正常水平(推理输入 160×160、INT8),并非异常。

  • 若需更高帧率,可减小推理输入分辨率、换用更轻量的风格模型,或降低显示分辨率。

  • 排查性能时可临时加 --frames 30 做定点压测,观察日志中的 FPS 是否稳定。

推理初始化失败

现象:

RuntimeError: rknn_init 失败: rknn_init 失败 ret=-1

解决方案:

  • 确认 /usr/lib/librknnrt.so 存在,且与模型版本匹配(本模型面向 RK3576,运行时 API 2.3.2 / 驱动 0.9.8)。

  • 确认使用的是 udnie-9_int8_rk3576.rknn,其他平台转换的模型无法在本板运行。

技术支持与贡献

如在使用过程中遇到问题,欢迎在 移远官方论坛 提交技术咨询,我们的技术支持团队将及时为您解答。

项目仓库: https://github.com/Quectel-Pi/demo-rknn-style-transfer

欢迎提交 Issue 反馈问题或 Pull Request 贡献代码改进!